﻿#ifndef YIMAGEDRAWER_H
#define YIMAGEDRAWER_H

#include <QWidget>
// add by liq 11
#include <QGraphicsPixmapItem>
#include <QFrame>
#include <QPlainTextEdit>
#include <QGraphicsScene>
#include <QUndoStack>

class QGraphicsView;
class QGraphicsScene;
class QGraphicsItem;
class DrawTools;
//class QUndoView;
namespace Y_Image_Drawer_GUI {
// modify by liq 13
class YGraphicsItem;
//class YGraphicsItem : public QObject, public QGraphicsItem{
//    Q_OBJECT
//signals:
//    void sigDeleteItem();
//};
class YGraphicsChangeItem;

// liqtest0617
class YGraphicsMosaicItem;

//class YGraphicsItem
//{
//public:
//    virtual ~YGraphicsItem(){}
//    virtual void rerect(const QRect& rect) {Q_UNUSED(rect);}
//    virtual void rerect(const QPoint& pos){
//        if(lastPos == pos) return;
//        lastPos = pos;
//        QRect rect;
//        rect.setX(qMin(startPos.x(), pos.x()));
//        rect.setY(qMin(startPos.y(), pos.y()));
//        rect.setRight(qMax(startPos.x(), pos.x()));
//        rect.setBottom(qMax(startPos.y(), pos.y()));
//        rerect(rect);
//    }
//    virtual void reChangePos(){}
//    virtual void showChange(){}
//    virtual void hideChange(){}
//    virtual void cursorChange(const QPointF&, YGraphicsChangeItem*){}
//    bool inChangeHover();
//public:
//    YImageDrawer::Type itemType;
//    QPoint startPos;
//    QPoint lastPos;
//    QVector<QPointF> changePos;
//    QList<YGraphicsChangeItem*> changeItem;
//    bool showChanged = false;
//    bool inChangeArea = false;
//    char AlignPadding[6];
//    QPointF pressPos;
//    int resizeType = 0;//0:移动,1:垂直水平,2:垂直,3:水平
//    char AlignPadding2[4];
//    YGraphicsChangeItem* cursorItem = nullptr;
//    bool activeWindowFocus = false;
//    int currentThickness;
//    QColor currentColor;

//};

// modify by liq 13 start
class YGraphicsTipItemPanel : public QFrame
{
    Q_OBJECT
public:
    YGraphicsTipItemPanel(QWidget*parent = 0);
    ~YGraphicsTipItemPanel(){
//        --count;
    }

    QColor color = Qt::red;
    static int count;
    int self;
    bool isShow;

signals:
    void sigPressPanel();

protected:
    virtual void paintEvent(QPaintEvent*) override;
    virtual void mousePressEvent(QMouseEvent *event) override;
//    virtual void mouseMoveEvent(QMouseEvent *event) override;
};

class YGraphicsTextItemRect : public QFrame
{
    Q_OBJECT
public:
    YGraphicsTextItemRect(QWidget*parent = 0);
    ~YGraphicsTextItemRect(){
    }

    QColor color = Qt::red;

signals:
    void sigPressRect();

protected:
    virtual void paintEvent(QPaintEvent*) override;
    virtual void mousePressEvent(QMouseEvent *event) override;
//    virtual void mouseMoveEvent(QMouseEvent *event) override;
};

class PlainTextEdit: public QPlainTextEdit
{
    Q_OBJECT
public:
    PlainTextEdit();
    explicit PlainTextEdit(QWidget *parent= nullptr);
    ~PlainTextEdit(){
    }

    void adjustSize();
    void setFont(const QFont& f);

//private:
    QSize m_baseSize;
    QSize m_minSize;

signals:
    void textUpdated(const QString& s);

public slots:
    void setTextColor(const QColor& c);

private slots:
    void emitTextUpdated();

protected:
    QVariant inputMethodQuery(Qt::InputMethodQuery property) const override;
    void showEvent(QShowEvent* e) override;
    void resizeEvent(QResizeEvent* e) override;
};

// modify by liq 13 end

class DiagramScene : public QGraphicsScene
{
    Q_OBJECT

public:
    DiagramScene(QRect rect, QObject *parent = nullptr);

signals:
    void sigItemMoved(QGraphicsItem *movedItem, const QPointF &movedFromPosition = QPointF(0,0), const QPoint &movedLastPos = QPoint(0,0));
    void sigItemSizeChanged(QGraphicsItem *sizeChangedItem, const QSizeF &changedSize);
    void sigDoUndoAction();
    void sigDoRedoAction();

protected:
    void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
    virtual void keyPressEvent(QKeyEvent *event) override;
    virtual void keyReleaseEvent(QKeyEvent *event) override;

private:
    QGraphicsItem *movingItem = nullptr;
    QGraphicsItem *keyPressMovingItem = nullptr;
    QPointF oldPos;
    QPointF keyPressOldPos;
    QPoint oldLastPos;
    QPoint keyPressOldLastPos;
//    QSizeF oldSize;
};

}

class YImageDrawer : public QWidget
{
    Q_OBJECT

public:
    enum Type{
        Rect = 1, Ellipse, Arrow, Pen, Mosaic, Text, Tip
    };
    // add by liq 13
    QImage basicImage;
    explicit YImageDrawer(const QImage& image, QRect& selectedRect, QWidget *parent = nullptr);
    void setType(int t);
    void setViewCursor(const QCursor& cursor);
    void setTools(DrawTools* t);
    void sortTipCount();
    DrawTools* tools;
    bool globalShiftKeyPressed = false;
    void UpdateToolSetting();

signals:
    // add by liq 12
    void sigDrawToolsReshow();
    void sigSaveScreenShot();
    void sigDownload();
    void sigStickerDesktop();
    void sigQuitScreenshot();
    void sigGetPinKey();
    // add by liq 14
    void sigScreenshotCancel();
//    void sigIsDrawing(bool isDraw);
    void sigUpdateThicknessSetting(int currentThickness);
    void sigUpdateColorSetting(QColor currentColor);
    void sigUpdateFontsizeSetting(int currentFontsize);
    void sigUpdateToolSetting(int itemType);
    void sigUpdateUndoBtnState(bool canUndo);
    void sigUpdateRedoBtnState(bool canRedo);

public slots:
    void thicknessChanged(int);
    void colorChanged(QColor);
    void fontChanged(const QFont&);
    void clearCount();
    void vagueChanged(int);
    void undo();
    void redo();
    // add by liq 11
    void updateYImageDrawer(const QImage& image, const QRect& rect, QWidget *parent = nullptr);
    // add by liq 12
    void changeItemPos(const QPoint& point);
    void onChangePinKey(const QString& key);
    void saveScreenShot();
    void download();
    void stickerDesktop();
    void quitScreenshot();
    void updateShiftKeyPressedVal(bool isPressed);
    void onDoUndoAction();
    void onDoRedoAction();
    void onItemMoved(QGraphicsItem *movedItem, const QPointF &moveStartPosition = QPointF(0,0), const QPoint &movedLastPos = QPoint(0,0));
    void onRectItemSizeChanged(QGraphicsItem *sizeChangedItem, const QPointF &oldPos, const QRectF &oldRect, const QSizeF &oldSize);
    void onEllipseItemSizeChanged(QGraphicsItem *sizeChangedItem, const QPointF &oldPos, const QRectF &oldRect, const QSizeF &oldSize);
    void onArrowItemSizeChanged(QGraphicsItem *sizeChangedItem, const QPointF &oldPos, const QPoint &oldLastPos);

protected:
    void createItem(const QPoint& pos, bool shiftKeyPressed = false);
    virtual void contextMenuEvent(QContextMenuEvent *) override;
    bool eventFilter(QObject*, QEvent*) override;

private:
    QImage image;
    QGraphicsView* view;
//    QGraphicsScene* scene;
    Y_Image_Drawer_GUI::DiagramScene* scene = nullptr;
    // add by liq 11
    QGraphicsPixmapItem *pm;
    Type type;
    Y_Image_Drawer_GUI::YGraphicsItem* currentItem = nullptr;
    bool pressed = false;
    bool shiftKeyPressed = false;
    QPoint startPos;
    QList<QGraphicsItem*> items;
    QList<QGraphicsItem*> allItems;
    Y_Image_Drawer_GUI::YGraphicsItem* focusItem = nullptr;
// liqtest0617
    Y_Image_Drawer_GUI::YGraphicsMosaicItem* mosaic;

    // 右键菜单对象
    QMenu *menu_;
    QUndoStack *m_undoStack = nullptr;
//    QUndoView *m_undoView = nullptr;
    QGraphicsItem *movingItem = nullptr;
    QPointF oldPos;
    int tipCnt = 0;
    QGraphicsItem* selectedGraphicsitem = nullptr;

};

namespace Y_Image_Drawer_GUI {
class YGraphicsItem
{
public:
    virtual ~YGraphicsItem(){}
    virtual void rerect(const QRect& rect) {Q_UNUSED(rect);}
    virtual void rerect(const QPoint& pos){
        if(lastPos == pos) return;
        lastPos = pos;
        QRect rect;
        rect.setX(qMin(startPos.x(), pos.x()));
        rect.setY(qMin(startPos.y(), pos.y()));
        rect.setRight(qMax(startPos.x(), pos.x()));
        rect.setBottom(qMax(startPos.y(), pos.y()));
        rerect(rect);
    }
    virtual void reChangePos(){}
    virtual void showChange(){}
    virtual void hideChange(){}
    virtual void cursorChange(const QPointF&, YGraphicsChangeItem*){}
    bool inChangeHover();
public:
    YImageDrawer::Type itemType;
    QPoint startPos;
    QPoint lastPos;
    QVector<QPointF> changePos;
    QList<YGraphicsChangeItem*> changeItem;
    bool showChanged = false;
    bool inChangeArea = false;
    char AlignPadding[6];
    QPointF pressPos;
    int resizeType = 0;//0:移动,1:垂直水平,2:垂直,3:水平
    char AlignPadding2[4];
    YGraphicsChangeItem* cursorItem = nullptr;
    bool activeWindowFocus = false;
    int currentThickness;
    QColor currentColor;
    int currentSize;
    int currentWeight;
    bool currentFontIsBold;
    int oldWidth = 0;
    int oldHeight = 0;
    QPointF oldPos;
    QPoint oldLastPos;
    QRectF oldRect;

};
}

#endif // YIMAGEDRAWER_H
